package com.kewill.jira.servlet;

import com.kewill.jira.common.JiraAttribute;
import com.kewill.jira.model.ActionDefinition;
import com.kewill.jira.util.DaoUtil;
import com.kewill.jira.util.JiraSyncUtil;
import com.kewill.jira.util.ServletUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.*;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;

/**
 * Created by YanJun on 2016/7/4.
 */
public class IssueBaseServlet extends HttpServlet {

    private Logger issueBaseServletLog = LoggerFactory.getLogger(IssueBaseServlet.class);
    private static List<ActionDefinition> actionDefinitionList;
    private HashMap<String,Object> actionClassCache = new HashMap<String,Object>();
    private String actionShowUrl = new String();
    private String actionClassName = new String();
    static{
        actionDefinitionList = JiraSyncUtil.analysisActionXml();
    }

    public IssueBaseServlet(){
        try {
            DaoUtil.setDao(this);
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        issueBaseServletLog.debug("Invoke BaseServlet Do Post ...");
        String requestPath = ServletUtil.getPathInfo(request);
        String requestType = request.getMethod();
        HashMap<String,Object> servletMetaMap = new HashMap<String, Object>();
        if(requestPath.contains("action")) {
            String actionName = ServletUtil.getActionName(requestPath);
            HashMap<String,String[]> paramMap = ServletUtil.getParamMap(request);
            servletMetaMap.put(JiraAttribute.PARAM_REQUEST,request);
            servletMetaMap.put(JiraAttribute.PARAM_RESPONSE,response);
            servletMetaMap.put(JiraAttribute.PARAM,paramMap);
            String methodName = ServletUtil.getParam(request,"method");
            issueBaseServletLog.debug("action --> " + actionName + ";" + " method --> " + methodName);
            try {
                ActionDefinition actionDefinition = getActionDefinitionByActionName(actionName,methodName,requestType);
                Object actionObj = null;
                actionClassName = actionDefinition.getActionClassName();
                actionShowUrl = actionDefinition.getShowUrl();
                if(actionClassCache.containsKey(actionClassName)){
                    actionObj = actionClassCache.get(actionClassName);
                }else{
                    Class clazz = Class.forName(actionClassName);
                    actionObj = clazz.newInstance();
                }
                Method[] methodArr = actionObj.getClass().getMethods();
                for (Method method : methodArr) {
                    String objMethodName = method.getName();
                    if (objMethodName.equals(methodName)
                            && !methodName.equals("show")
                            && requestType.equals(actionDefinition.getType().toUpperCase())) {
                        method.invoke(actionObj, servletMetaMap);
                    }else if(objMethodName.equals(methodName)
                            && methodName.equals("show")
                            && requestType.equals(actionDefinition.getType().toUpperCase())){
                        show(servletMetaMap);
                    }
                }
                actionClassCache.put(actionClassName,actionObj);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }

    }

    public void show(HashMap<String,Object> servletMetaMap)
            throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest)servletMetaMap.get(JiraAttribute.PARAM_REQUEST);
        HttpServletResponse response = (HttpServletResponse)servletMetaMap.get(JiraAttribute.PARAM_RESPONSE);
        issueBaseServletLog.debug("invoke " + actionClassName + ".show()");
        response.sendRedirect(request.getContextPath() + actionShowUrl);
    }

    private ActionDefinition getActionDefinitionByActionName(String actionName,String methodName,String requestType) {
        for(ActionDefinition actionDefinition:actionDefinitionList){
            if(actionDefinition.getActionName().equals(actionName)
                    && actionDefinition.getActionMethodName().equals(methodName)
                    && actionDefinition.getType().equals(requestType.toLowerCase())){
                return actionDefinition;
            }
        }
        return null;
    }
}
